#region Imported Namespaces


using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;

using WtfManager.HierarchicalData;
using WtfManager.WindowsNative.Shell32;

using FileInfo=WtfManager.WindowsNative.Shell32.FileInfo;


#endregion


namespace WtfManager.FileManager
{
  ///<summary>
  /// Describes and manipulates Windows My Computer virtual folder.
  ///</summary>
  public class MyComputer: FileSystemItem
  {
    #region Constructors/Finalizers


    ///<summary>
    /// Default MyComputer constructor.
    ///</summary>
    public MyComputer()
    {
      const FileInfo flags = FileInfo.SHGFI_DISPLAYNAME | FileInfo.SHGFI_ATTRIBUTES | FileInfo.SHGFI_TYPENAME;

      var pidl = new Pidl(Environment.SpecialFolder.MyComputer, flags);
      Name = pidl.DisplayName;
    }


    #endregion


    #region Properties/Indexers


    public override bool IsMovable
    {
      get
      {
        return false;
      }
    }

    public override bool IsFile
    {
      get
      {
        return false;
      }
    }

    public override bool IsHidden
    {
      get
      {
        return false;
      }
    }


    #endregion


    #region Methods


    ///<summary>
    /// Gets an icon of a file system item.
    ///</summary>
    ///<returns>Returns <see cref="Icon"/>.</returns>
    protected override Icon GetIcon(FileInfo flags)
    {
      var pidl = new Pidl(Environment.SpecialFolder.MyComputer, flags);

      return pidl.Icon;
    }


    ///<summary>
    /// Gets file system path of an item.
    ///</summary>
    ///<returns>a string containing file system path of an item.</returns>
    protected override string GetFileSystemPath()
    {
      return null;
    }


    protected override void OnRefresh()
    {
      DriveInfo[] drives = DriveInfo.GetDrives();

      RemovedUnexistingItems(drives);

      AddNewItems(drives);
    }


    private void AddNewItems(IEnumerable<DriveInfo> drives)
    {
      foreach (DriveInfo driveInfo in drives)
      {
        string name = driveInfo.Name[0] + ":";

        if (Children.Contains(name))
        {
          continue;
        }

        var drive = new FileSystemDrive(name);
        AddChild(drive);
      }
    }


    private void RemovedUnexistingItems(IEnumerable<DriveInfo> drives)
    {
      var itemsToRemove = new List<TreeItem>();

      foreach (TreeItem item in Children)
      {
        if (!ItemExists(drives, item))
        {
          itemsToRemove.Add(item);
        }
      }

      foreach (TreeItem item in itemsToRemove)
      {
        RemoveChild(item);
      }
    }


    private static bool ItemExists(IEnumerable<DriveInfo> drives, TreeItem item)
    {
      foreach (DriveInfo drive in drives)
      {
        if (drive.Name == item.Name)
        {
          return true;
        }
      }

      return false;
    }


    #endregion
  }
}